'use strict';
const moment = require('moment');
const path = require('path');
const FormData = require('form-data');
const axios = require('axios');
const { fileMapPath } = require('../utils/constant');

const Service = require('egg').Service;

class fileService extends Service {
  async batchFile(parts) {
    const { ctx } = this;
    let part;
    const fileInfoList = [];
    while ((part = await parts()) != null) {
      const filename = part.filename;
      if (!filename) {
        continue;
      }
      try {
        // 将流储存一份 toBuffer
        const buffer = await ctx.service.toBuffer.index(part);
        const hash = await ctx.service.toBuffer.buffertoHash(buffer);
        const fileObj = {
          part: buffer,
          hash,
          extname: path.extname(filename),
        };
        fileInfoList.push(fileObj);
      } catch (error) {
        console.log(error, 'error123');
      }
    }
    for (const key in parts.field) {
      if (Object.hasOwnProperty.call(parts.field, key)) {
        const value = parts.field[key];
        if (Array.isArray(value)) {
          for (let index = 0; index < value.length; index++) {
            const fileText = value[index];
            fileInfoList[index][key] = fileText;
          }
        } else {
          fileInfoList[0][key] = value;
        }
      }
    }
    const duplicateList = await ctx.service.common.duplicate(fileInfoList);
    let message = '';
    if (duplicateList.length > 0) {
      for (let index = 0; index < duplicateList.length; index++) {
        message += duplicateList[index];
      }
      return await ctx.service.returnBody.index(null, message);
    }
    // 上传文件到oss
    const resultList = await this.addOssInfoHandler(fileInfoList);
    // 添加到数据库
    const appendList = [];
    // 批次号
    const batchNo = await this.getBtchNo();
    const now = new Date();
    const sessionInfo = ctx.session.sessionInfo;
    for (let index = 0; index < fileInfoList.length; index++) {
      const item = fileInfoList[index];
      const obj = {
        status: 1, // 文件状态
        createdTime: now, // 创建时间
        updatedTime: now, // 更新时间
        createId: sessionInfo.id, // 创建人ID
      };
      obj.batchNo = batchNo; // 批次号
      obj.hash = item.hash; // md5
      obj.fileName = item.fileName; // 文件名
      obj.relatedUrl = item.relatedUrl; // 下载地址
      obj.fileDesc = item.fileDesc; // 功能描述
      obj.fileUrl = resultList[index]; // 文件地址
      appendList.push(obj);
    }
    await this.ctx.model.File.bulkCreate(appendList);
    return await ctx.service.returnBody.index({}, '上传失败！');
  }


  // 组装上传到oss信息
  async addOssInfoHandler(fileInfoList) {
    const { ctx } = this;
    const ossUrl = ctx.app.config.ossUrl;

    const results = [];
    for (let ind = 0; ind < fileInfoList.length; ind++) {
      const item = fileInfoList[ind];
      try {
        // ossUpload
        const itemObj = {
          url: ossUrl.ossUpload, // 接口地址
          file: item.part,
          fileName: item.fileName,
          filename: '',
        };
        for (const key in fileMapPath) {
        // 网址
          if (Object.hasOwnProperty.call(fileMapPath, key)) {
            const fileDirName = fileMapPath[key];
            const url = new URL(item.relatedUrl).hostname.toLowerCase();
            if (url.includes(key)) {
              itemObj.filename = `${fileDirName}/${item.fileName}${item.extname}`;
              break;
            } else {
              const domin = url.split('.')[0];
              itemObj.filename = `Other/${domin}/${item.fileName}${item.extname}`;
            }
          }
        }
        results.push(await this.getOssUrl(itemObj));
      } catch (error) {
        console.log('error', error);
      }
    }
    return await Promise.all(results);
  }
  async getOssUrl(itemObj) {
    const data = new FormData();
    data.append('file', itemObj.file, itemObj.filename);
    const config = {
      method: 'POST',
      url: itemObj.url,
      headers: {
        ...data.getHeaders(),
      },
      data,
    };
    try {
      const result = await axios(config);
      if (result.data && result.data.code === 200) {
        return result.data.msg[0].url;
      }
    } catch (error) {
      console.log(error, 'errorerrorerror->getOssUrl');
      throw error;
    }
  }
  // 生成批次号
  async getBtchNo() {
    const { ctx } = this;
    const valueOf = moment().valueOf();
    const batchNo = `PC${String(valueOf).slice(-8)}`;
    const hasBatchNo = await ctx.model.File.findOne({
      attributes: [ 'id' ],
      where: {
        batchNo,
      },
    });
    if (hasBatchNo) {
      await this.getSrmNo();
    } else {
      return batchNo;
    }
  }
  async getFileHistory(params) {
    const ctx = this.ctx;
    const { offset, pageSize, createdTimeStart, createdTimeEnd, status, phoneNo, nickName } = params;
    const body = {
      totalCount: 0,
      fileTotalCount: 0,
      paidCount: 0,
      unPaidCount: 0,
      list: [],
    };
    const commonSql = `
    from file 
    left join user on user.id = file.create_id
    where 1 = 1
    ${createdTimeStart ? `and file.created_time >= '${createdTimeStart}'` : ''}
    ${createdTimeEnd ? `and file.created_time < '${createdTimeEnd}'` : ''}
    ${status > 0 ? `and file.status = ${status}` : ''}
    ${phoneNo ? `and user.phone_no = ${phoneNo}` : ''}
    ${nickName ? `and user.nick_name like '%${nickName}%'` : ''}`;
    const totalSql = `
      SELECT count(*) AS total
      ${commonSql}
    `;
    const fileTotalCountSql = `
      SELECT count(*) AS total from file
    `;
    const paidCountSql = `
      SELECT count(*) AS total from file where status = 2
    `;
    const unPaidCountSql = `
      SELECT count(*) AS total from file where status != 2
    `;
    const totalModel = await ctx.model.query(totalSql, { type: 'SELECT' });
    body.totalCount = totalModel && totalModel[0].total;
    const fileTotalModel = await ctx.model.query(fileTotalCountSql, { type: 'SELECT' });
    body.fileTotalCount = fileTotalModel && fileTotalModel[0].total;
    const paidCountModel = await ctx.model.query(paidCountSql, { type: 'SELECT' });
    body.paidCount = paidCountModel && paidCountModel[0].total;
    const unPaidCountModel = await ctx.model.query(unPaidCountSql, { type: 'SELECT' });
    body.unPaidCount = unPaidCountModel && unPaidCountModel[0].total;
    if (body.totalCount === 0) {
      return await ctx.service.returnBody.index(body, '获取文件历史记录失败！');
    }
    const Sql = `select
    file.id as id,
    user.nick_name as nickName,
    user.phone_no as phoneNo,
    file.file_name as fileName,
    file.batch_no as batchNo,
    file.message as message,
    file.status as status,
    DATE_FORMAT( file.created_time,'%Y-%m-%d %H:%i:%s') as createdTime
    ${commonSql}
    order by file.created_time desc
    ${pageSize ? `limit ${offset}, ${pageSize}` : ''}`;
    const Model = await ctx.model.query(Sql, { type: 'SELECT' });
    if (Model) {
      body.list = Model;
    }
    return await ctx.service.returnBody.index(body, '获取文件历史记录失败！');
  }
}

module.exports = fileService;
